package com.iwuyc.tools.commons.util.crypto;

import com.iwuyc.tools.commons.util.string.StringUtils;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.io.FileInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

@Slf4j
public class HashUtil {
    /**
     * 计算文件的MD5值
     *
     * @param file 文件
     * @return MD5值
     * @author 吴宇春
     * @version 1.0.0
     * @since 2025-07-27
     */
    public static String md5(File file) {
        return digest(file, DigestTypeEnum.MD5);
    }

    /**
     * 计算文件的MD5值
     *
     * @param file 文件
     * @return MD5值
     * @author 吴宇春
     * @version 1.0.0
     * @since 2025-07-27
     */
    public static String sha512(File file) {
        return digest(file, DigestTypeEnum.SHA512);
    }

    /**
     * 计算文件的MD5值
     *
     * @param file 文件
     * @return MD5值
     * @author 吴宇春
     * @version 1.0.0
     * @since 2025-07-27
     */
    public static String sha384(File file) {
        return digest(file, DigestTypeEnum.SHA384);
    }
    /**
     * 计算文件的MD5值
     *
     * @param file 文件
     * @return MD5值
     * @author 吴宇春
     * @version 1.0.0
     * @since 2025-07-27
     */
    public static String sha256(File file) {
        return digest(file, DigestTypeEnum.SHA256);
    }

    /**
     * 计算文件的SHA1值
     *
     * @param file 文件
     * @return SHA1值
     */
    public static String sha1(File file) {
        return digest(file, DigestTypeEnum.SHA1);
    }

    /**
     * 根据摘要算法的枚举，计算文件的摘要值
     *
     * @param file       文件
     * @param digestType 摘要算法枚举
     * @return 摘要值
     */
    public static String digest(File file, final DigestTypeEnum digestType) {
        if (file == null || !file.exists() || !file.isFile()) {
            throw new IllegalArgumentException("file is null or not exists");
        }
        try (FileInputStream fis = new FileInputStream(file)) {
            final MessageDigest md = MessageDigest.getInstance(digestType.getDigestCode());
            byte[] bytes = new byte[1024];
            int length;
            while ((length = fis.read(bytes)) != -1) {
                md.update(bytes, 0, length);
            }
            final byte[] digest = md.digest();
            return StringUtils.byteToHexString(digest);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    /**
     * MD5
     *
     * @param text 文本
     * @return MD5
     */
    public static String md5(String text) {
        return digest(text, DigestTypeEnum.MD5);
    }

    /**
     * SHA512
     *
     * @param text 文本
     * @return SHA512
     */
    public static String sha512(String text) {
        return digest(text, DigestTypeEnum.SHA512);
    }
    /**
     * SHA384
     *
     * @param text 文本
     * @return SHA384
     */
    public static String sha384(String text) {
        return digest(text, DigestTypeEnum.SHA384);
    }
    /**
     * SHA256
     *
     * @param text 文本
     * @return SHA256
     */
    public static String sha256(String text) {
        return digest(text, DigestTypeEnum.SHA256);
    }
    /**
     * SHA1
     *
     * @param text 文本
     * @return SHA1
     */
    public static String sha1(String text) {
        return digest(text, DigestTypeEnum.SHA1);
    }

    /**
     * 根据摘要算法类型，计算文本的摘要信息
     *
     * @param text       待计算文本
     * @param digestType 摘要算法类型
     * @return 摘要信息
     */
    public static String digest(String text, DigestTypeEnum digestType) {
        try {
            final MessageDigest md = MessageDigest.getInstance(digestType.getDigestCode());
            byte[] digest = md.digest(text.getBytes());
            return StringUtils.byteToHexString(digest);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }

}
